package com.summer.filesync.model;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/** 网络通信消息 节点间通信的基础消息格式 */
public class Message implements Serializable {
  private static final long serialVersionUID = 1L;

  public enum MessageType {
    // 系统消息
    HEARTBEAT, // 心跳消息
    NODE_JOIN, // 节点加入
    NODE_LEAVE, // 节点离开

    // 同步消息
    SYNC_REQUEST, // 同步请求
    SYNC_RESPONSE, // 同步响应
    FILE_LIST_REQUEST, // 文件列表请求
    FILE_LIST_RESPONSE, // 文件列表响应

    // 文件传输消息
    FILE_TRANSFER_REQUEST, // 文件传输请求
    FILE_TRANSFER_RESPONSE, // 文件传输响应
    FILE_CHUNK, // 文件块
    FILE_TRANSFER_COMPLETE, // 文件传输完成

    // 冲突处理消息
    CONFLICT_DETECTED, // 冲突检测
    CONFLICT_RESOLUTION // 冲突解决
  }

  private String messageId; // 消息唯一标识
  private MessageType type; // 消息类型
  private String sourceNodeId; // 源节点ID
  private String targetNodeId; // 目标节点ID（null表示广播）
  private Object payload; // 消息载荷
  private long timestamp; // 时间戳
  private Map<String, String> headers; // 消息头

  public Message() {
    this.messageId = UUID.randomUUID().toString();
    this.timestamp = System.currentTimeMillis();
    this.headers = new HashMap<>();
  }

  public Message(MessageType type, String sourceNodeId) {
    this();
    this.type = type;
    this.sourceNodeId = sourceNodeId;
  }

  public Message(MessageType type, String sourceNodeId, String targetNodeId, Object payload) {
    this(type, sourceNodeId);
    this.targetNodeId = targetNodeId;
    this.payload = payload;
  }

  /** 添加消息头 */
  public void addHeader(String key, String value) {
    headers.put(key, value);
  }

  /** 获取消息头 */
  public String getHeader(String key) {
    return headers.get(key);
  }

  /** 检查是否为广播消息 */
  public boolean isBroadcast() {
    return targetNodeId == null;
  }

  /** 创建响应消息 */
  public Message createResponse(MessageType responseType, Object responsePayload) {
    Message response = new Message(responseType, targetNodeId, sourceNodeId, responsePayload);
    response.addHeader("originalMessageId", this.messageId);
    return response;
  }

  @Override
  public String toString() {
    return "Message{"
        + "messageId='"
        + messageId
        + '\''
        + ", type="
        + type
        + ", sourceNodeId='"
        + sourceNodeId
        + '\''
        + ", targetNodeId='"
        + targetNodeId
        + '\''
        + ", timestamp="
        + timestamp
        + '}';
  }

  // Getters and Setters
  public String getMessageId() {
    return messageId;
  }

  public void setMessageId(String messageId) {
    this.messageId = messageId;
  }

  public MessageType getType() {
    return type;
  }

  public void setType(MessageType type) {
    this.type = type;
  }

  public String getSourceNodeId() {
    return sourceNodeId;
  }

  public void setSourceNodeId(String sourceNodeId) {
    this.sourceNodeId = sourceNodeId;
  }

  public String getTargetNodeId() {
    return targetNodeId;
  }

  public void setTargetNodeId(String targetNodeId) {
    this.targetNodeId = targetNodeId;
  }

  public Object getPayload() {
    return payload;
  }

  public void setPayload(Object payload) {
    this.payload = payload;
  }

  public long getTimestamp() {
    return timestamp;
  }

  public void setTimestamp(long timestamp) {
    this.timestamp = timestamp;
  }

  public Map<String, String> getHeaders() {
    return headers;
  }

  public void setHeaders(Map<String, String> headers) {
    this.headers = headers;
  }
}
